# 导入相关库和模块
from contextlib import contextmanager
from typing import Union
from database import SessionLocal
import sys
from typing import List
from config.logging import logger
from services.database_manager import databaseManager
from models.admin_menu import AdminMenu
from models.admin_user import AdminUser
from collections import defaultdict
from config.logging import logger


# 定义服务类
class MenuApiService:
    def __init__(self, db):
        self.db = db
        self.db_manager = databaseManager(self.db)

    async def create_menu(self, data: dict):
        """
        创建菜单
        """
        param = self.db_manager.snake_convert_dict_keys(data)
        error = await self.check_parent_menu_exists(param)
        if error:
            return error
        param['parent_id'] = None if param['parent_id'] == 0 else param['parent_id']
        param['permission_id'] = None if param['permission_id'] == 0 else param['permission_id']
        change = self.db_manager.snake_convert_dict_keys(param)
        logger.info(f"类型{type(change)}")
        res = self.db_manager.create_entry(AdminMenu, change)
        logger.info(f"结果{res}")
        return self.db_manager.convert_dict_keys(res)

    async def menu_list(self, page: int, limit: int) -> List[dict]:
        """
        菜单列表
        """
        query = self.db.query(AdminMenu)
        lists = self.db_manager.paginate_query(query, page, limit)
        return [self.db_manager.convert_dict_keys(menu.to_dict()) for menu in lists] if lists else []

    async def menu_detail(self, menuId: int) -> Union[dict, None]:
        """
        菜单详情
        """
        info = self.db_manager.detail_query(AdminMenu, {"id": menuId})
        if info and info['parent_id'] != 0:
            pid_info = self.db_manager.detail_query(AdminMenu, {"id": info['parent_id']},
                                                    fields=["id", "menu_name"])
            info['parent_info'] = pid_info if pid_info else None
        return self.db_manager.convert_dict_keys(info) if info else None

    async def update_menu(self, menuId: int, data: dict):
        """
        更新菜单
        """

        param = self.db_manager.snake_convert_dict_keys(data)
        error = await self.check_parent_menu_exists(param)
        if error:
            return error
        param['parent_id'] = None if param['parent_id'] == 0 else param['parent_id']
        param['permission_id'] = None if param['permission_id'] == 0 else param['permission_id']
        res = self.db_manager.detail_update(AdminMenu, {"id": menuId}, param)
        return res

    async def delete_menu(self, menuId: int):
        """
        删除菜单
        """
        res = self.db_manager.delete_records_by_ids(AdminMenu, menuId)
        return res

    from collections import defaultdict

    async def user_menu(self, user_info: dict):
        """
            用户对应权限的菜单
            """
        user = self.db.query(AdminUser).filter(AdminUser.id == user_info['id']).first()
        if not user:
            return {'error': "用户不存在"}

        roles = user.roles
        # 收集所有角色的权限，使用set避免权限重复
        permissions = set()
        for role in roles:
            permissions.update(role.permissions)

        # 基于权限收集可以访问的菜单项的ID
        menu_ids = set()
        for perm in permissions:
            # 假设Permission模型中有指向Menu的关系
            menu_ids.update([menu.id for menu in perm.menus])

        # 根据收集到的菜单ID查询菜单项
        menus = self.db.query(AdminMenu).filter(AdminMenu.id.in_(list(menu_ids))).all()

        # 构建菜单树
        menu_tree = await self.build_menu_tree(menus)

        return [self.db_manager.convert_dict_keys(menu) for menu in menu_tree]

    async def build_menu_tree(self, menus):
        tree = defaultdict(lambda: {
            'children': [],
            'parent_id': None,
            'id': None,
            'selected': None,
            'type': None,
            'path': None,
            'title': None,
            'params': None,
            'component': None,
            'redirect': None,
            'icon': None,
            'is_link': False,
            'target': '_self',
            'is_tabs': False,
            'is_cache': False,
            'is_breadcrumb': True,
            'is_hidden': False,
            'permission_id': None,
            'sort': 0,
            'status': 0,
            'permissions': []  # 加上权限信息
        })

        for menu in menus:
            menu_dict = menu.to_dict()
            menu_dict['permissions'] = [perm.to_dict() for perm in menu.permissions]
            tree[menu.id].update(menu_dict)
            if menu.parent_id is not None:
                tree[menu.parent_id]['children'].append(tree[menu.id])

        root_menus = [menu for menu in tree.values() if menu['parent_id'] is None]
        return root_menus

    async def check_parent_menu_exists(self, param):
        """
        检查是否有parent_id
        """
        parent_id = int(param.get("parent_id", 0))
        if parent_id != 0:
            pid_exists = self.db_manager.detail_query(AdminMenu, {"id": parent_id})
            if not pid_exists:
                return {"error": "父菜单不存在"}
        return None
